package com.atguigu.spring.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

//生成动态代理类的工厂类
public class ProxyFactory {

    //需要代理的目标对象，我们并不知道目标类的类型，因此使用Object
    private Object target;

    public ProxyFactory(Object target){
        this.target=target;
    }

    //通过JDK和反射获取动态代理类对象
    public Object getProxy(){
        /*newProxyInstance的三个参数：
        ClassLoader loader：指定一个加载器来加载动态生成的代理类
        三种加载器：根、拓展、系统（应用）
        Class<?>[] interfaces:获取目标对象实现的所有接口
        InvocationHandler h:设置代理类中的方法如何重写目标类实现的接口的方法
         */

        //获取系统类加载器
        ClassLoader classLoader =this.getClass().getClassLoader();
        //代理类需要和目标类有相同的方法，因此我们需要获取目标对象实现的所有接口的Class对象
        Class interfaces[] =target.getClass().getInterfaces();
        //InvocationHandler h:设置代理类中的方法如何重写目标类中的方法
        InvocationHandler h = new InvocationHandler() {
            @Override
            /*
            proxy：代理类
            method：要重写的方法
            args：method的参数列表
             */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object result = null;
                try {
                    //功能执行之前
                     System.out.println("日志： 方法："+method.getName()+"参数："+ Arrays.toString(args));
                    //代理类中的方法要调用目标类中的方法
                     result = method.invoke(target,args);
                    //功能执行之后
                     System.out.println("日志： 方法："+method.getName()+"结果:"+result);
                } catch (Exception e) {
                    //抛出异常时
                    e.printStackTrace();
                    System.out.println("日志： 方法："+method.getName()+"异常："+ e);

                }finally {
                    //执行完毕时
                    System.out.println("日志： 方法："+method.getName()+"执行结束");
                }
                return result;

            }
        };
        return Proxy.newProxyInstance(classLoader,interfaces,h);
    }
}
